<template>
  <view class="list">
    <view v-if="isSearch" class="search-box">
      <view class="input-box">
        <input v-model="search" type="text" :placeholder="placeholder" />
      </view>
      <view v-if="search" class="clear" @click="clearSearch">重置</view>
    </view>
    <scroll-view
      scroll-y
      :style="scrollViewStyle"
      refresher-enabled
      :refresher-triggered="refreshTriggered"
      @refresherrefresh="onRefresh"
      @scrolltolower="onScrollTolower"
    >
      <view v-if="list.length > 0">
        <slot :list="list" />
        <view class="list-load_more">
          <u-loadmore
            :status="status"
            :loading-text="loadingText"
            :loadmore-text="loadmoreText"
            :nomore-text="nomoreText"
            marginBottom="0"
            marginTop="0"
          />
        </view>
      </view>
      <view style="padding-top: 50rpx" v-else>
        <NoData margin="0" />
      </view>
    </scroll-view>
  </view>
</template>
<script setup lang="ts">
import { computed, ref } from "vue";
import useLoadMore from "./hooks/useLoadMore";
import { watch } from "vue";

export interface ListProps {
  search?: string; // 搜索值双向绑定，外层v-model:search绑定
  isSearch?: boolean; // 是否显示搜索栏
  placeholder?: string; // 搜索栏的placeholder
  scrollHeight?: number | string;
  scrollStyle?: any;
  api?: (params?: any) => ListApiPromise<any>;
  params?: any;
  scrollBgColor?: string;
}

const props = withDefaults(defineProps<ListProps>(), {
  search: "",
  isSearch: false,
  placeholder: "请输入搜索内容",
});

const search = defineModel("search", {
  type: String,
  default: "",
});

const list = ref<any[]>([]);

const requestParams = ref({
  page: 1,
  limit: 10,
});

const pageParams = ref({
  total: 7, // 总条数
  countPage: 1, // 总页数
});

const { status, loadingText, loadmoreText, nomoreText } = useLoadMore();

const refreshTriggered = ref(false);

const scrollViewStyle = computed(() => {
  const { scrollHeight, scrollStyle, scrollBgColor, isSearch } = props;
  return {
    ...scrollStyle,
    height: scrollHeight
      ? typeof scrollHeight === "number"
        ? scrollHeight + "rpx"
        : scrollHeight
      : isSearch
      ? "calc(100vh - 120rpx)"
      : "100vh",
    background: scrollBgColor ?? "transparent",
  };
});

// 触发刷新
const onRefresh = async () => {
  requestParams.value.page = 1;
  refreshTriggered.value = true;
  await getList();
  refreshTriggered.value = false;
};

// 滚动到底部
const onScrollTolower = async () => {
  console.log("滚动到底部，可做加载更多操作");
  const { countPage } = pageParams.value;

  const { page } = requestParams.value;

  if (page < countPage) {
    requestParams.value.page = page + 1;
    await getList({
      isPush: true,
    });
  }
};

const getList = async (options?: { params?: any; isPush?: boolean }) => {
  const { params: optionsParams, isPush } = options || {};
  const { api, params } = props;
  if (api) {
    try {
      status.value = "loading";
      const res = await api({
        ...requestParams.value,
        ...params,
        ...optionsParams,
      });
      const { page, countPage, data, total } = res;

      pageParams.value = {
        total,
        countPage,
      };

      requestParams.value.page = page;

      if (isPush) {
        list.value = [...list.value, ...data];
      } else {
        list.value = data;
      }
      status.value = page <= countPage ? "nomore" : "loadmore";
      console.log("请求列表成功", res);
    } catch (error) {
      console.log("请求列表失败", error);
    }
  }
};

const clearSearch = () => {
  search.value = "";
};

watch(
  () => props.api,
  (newVal) => {
    if (newVal) {
      getList();
    }
  },
  {
    deep: true,
    immediate: true,
  }
);
</script>
<style lang="scss" scoped>
.list {
  .search-box {
    width: 100%;
    height: 120rpx;
    display: flex;
    align-items: center;
    padding: 20rpx 30rpx;
    background-color: #fff;
    .input-box {
      width: 100%;
      height: 100%;
      background-color: #f0f0f0;
      border-radius: 36rpx;
      padding: 0 20rpx;
      display: flex;
      align-items: center;
      input {
        font-size: 28rpx;
      }
    }
    .clear {
      white-space: nowrap;
      font-size: 28rpx;
      color: #222;
      margin-left: 20rpx;
    }
  }
  .list {
    box-sizing: border-box;
    .list-load_more {
      // margin-bottom: 50rpx;
      padding: 20rpx 0 60rpx 0;
    }
  }
}
</style>
